package serverApp.server;

import java.io.*;
import java.net.*;
import java.util.*;
import java.sql.*;

import javax.swing.SwingUtilities;

import serverApp.threads.SMSClient;
import serverApp.threads.WritingThread;

import netInterfaces.*;

public class StimMessageServer {
	
	private ServerSocket server;
	private Socket connection;
	private ObjectOutputStream output;
	private ObjectInputStream input;
	private String login, password;
	private Connection connectionDB;
	private Statement statement;
	private ResultSet resultSet;
	
	//запустить сервер
	public void startServer(){
		
		//создать сервер и обслуживать новых клиентов
		try {
			server = new ServerSocket(SocketMessengerConstants.SERVER_PORT, 100);
			
			System.out.println("Server listening on port: "+SocketMessengerConstants.SERVER_PORT);
			
			//подключится к базе данных
			try {
				Class.forName(SocketMessengerConstants.MYSQL_JDBC_DRIVER);
				connectionDB = DriverManager.getConnection(SocketMessengerConstants.DATABASE_URL,
						"root", "DvY02061989");
				statement = connectionDB.createStatement();
			}
			catch (ClassNotFoundException exp){
				exp.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				System.out.println("Can't connected to DB ---> "+e);
			}
			//слушать клиентов всегда
			while (true){
				try {
					waitForConnection();
					getStreams();
					if (checkLogin()){
						processConnection();
					}
				}
				catch (EOFException exp){
					System.out.println("Terminated connection");
				}
				finally {
					closeConnection();
				}
			}
		}
		catch (IOException exp){
			exp.printStackTrace();
		}
	}
	
	
	//метод, который выводит информацию о работе сервера на экран
	private void displayMessage(final String message){
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println(message);
			}
		});
	}
	
	//ждать соединение и вывести информацию о коннекте
	private void waitForConnection(){
		try {
			connection = server.accept();
			displayMessage("Get connection from: "+connection.getInetAddress().getHostAddress());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//получить потоки для отправки и приема соощений
	private void getStreams() throws IOException{
		//получить выходной поток
		output = new ObjectOutputStream(connection.getOutputStream());
		output.flush();
		
		//получить входной поток
		input = new ObjectInputStream(connection.getInputStream());
		displayMessage("get i/o Streams");
	}
	
	//проверить логин и пароль
	private boolean checkLogin(){
		String message;
		String tryLogin = "", tryPassword = "";
		
		
		try{
			message = (String) input.readObject();
			if (message != null){
				StringTokenizer tokenizer = new StringTokenizer(message, SocketMessengerConstants.MESSAGE_SEPARATOR);
				login = tokenizer.nextToken();
				password = tokenizer.nextToken();
			}
			else {
				login = "";
				password = "";
			}
			
		}
		catch (ClassNotFoundException exp){
			exp .printStackTrace();
		}
		catch (IOException exp){
			exp.printStackTrace();
		}
		
		//проверить правильность логина и пароля
		try {
			resultSet = statement.executeQuery("Select loginName, password from users where loginName Like" +
					"'"+login+"'");
			while (resultSet.next()){
				tryLogin = resultSet.getString("loginName");
				tryPassword = resultSet.getString("password");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if (login.equals(tryLogin) && password.equals(tryPassword)){
			sendData(SocketMessengerConstants.CONNECT_STRING);
			message = null;
			return true;
		}
		else {
			sendData(SocketMessengerConstants.DISCONNECT_STRING);
			message = null;
			return false;
		}
	}
	
	//обработка соединения
	private void processConnection() throws IOException{
		Message message;
		SMSClient smsClient = new SMSClient();
		String statusMessage = "";
		String author, theme, text, date, time;
		String numbersBuffer;
		int authorID = -1, groupID = -1;
		
		do {
			//прочитать и записать сообщение
			try {
				statusMessage = (String) input.readObject();
				if (statusMessage.equals(SocketMessengerConstants.TRANSMISSION_START)){
					message = (Message)input.readObject();
					author = message.getMessageAuthor();
					theme = message.getMessageTheme();
					text = message.getMessageText();
					date = message.getMessageDate();
					time = message.getMessageTime();
					try {
						//находим userID по имени логина автора
						resultSet = statement.executeQuery("Select userID from users where loginName like '"+author+"'");
						while (resultSet.next()){
							authorID = resultSet.getInt("userID");
						}
						//записываем сообщение в БД 
						statement.executeUpdate("Insert into messages " +
								"(messageTheme, messageText, messageDate, messageTime, userID)" +
								"values ('"+theme+"', '"+text+"', '"+date+"', '"+time+"', '"+authorID+"')");
						
						//отбираем номера телефонов
						resultSet = statement.executeQuery("Select groupID from students where userID = '"+authorID+"'");
						while (resultSet.next()){
							groupID = resultSet.getInt("groupID");
						}
						resultSet = statement.executeQuery("Select phoneNumber from students " +
								"where groupID = '"+groupID+"'");
						while (resultSet.next()){
							numbersBuffer = (resultSet.getString("phoneNumber"));
							System.out.println(numbersBuffer);
							smsClient.sendMessage("+38"+numbersBuffer, SocketMessengerConstants.SMS_MESSAGE);
							while (smsClient.status == -1);
							smsClient.status = -1;
						}
					}
					catch (SQLException exp){
						exp.printStackTrace();
					}
					
					
					
					//new WritingThread(author, theme, text, date).start();
					//sendData(SocketMessengerConstants.DONE);
				}
				else if (statusMessage.equals(SocketMessengerConstants.OPEN_DATA)) {
					//открыть файл из БД
				}
				
			}
			catch (ClassNotFoundException exp){
				System.out.println("Get bad Object");
			}
		} while (!statusMessage.equals(SocketMessengerConstants.DISCONNECT_STRING));
	}
	
	//отправка сообщения клиенту
	private void sendData(String message){
		//послать обьект
		try{
			output.writeObject(message);
			output.flush();
		}
		catch (IOException exp) {
			exp.printStackTrace();
		}
	}
	
	//зарыть соединения
	private void closeConnection(){
		System.out.println("Close Connection");
		
		try {
			output.close();
			input.close();
			connection.close();
			login = null;
			password = null;
		}
		catch (IOException exp){
			exp.printStackTrace();
		} 
	}
	
	public static void main(String args[]){
		new StimMessageServer().startServer();
	}
}
